#ifndef HIERARCHICAL_CACHE_H
#define HIERARCHICAL_CACHE_H

#include "memory_cache.h"
#include "disk_cache.h"
#include <memory>
#include <chrono>
#include <thread>
#include <atomic>

// 分层缓存管理器
// 协调L1（内存缓存）和L2（磁盘缓存）的工作
template<typename KeyType, typename ValueType>
class HierarchicalCache {
private:
    std::unique_ptr<MemoryCache<KeyType, ValueType>> l1_cache_;   // L1缓存（内存）
    std::unique_ptr<DiskCache<KeyType, ValueType>> l2_cache_;     // L2缓存（磁盘）

    // 统计信息
    std::atomic<size_t> total_requests_;                           // 总请求数
    std::atomic<size_t> l1_hits_;                                  // L1命中数
    std::atomic<size_t> l2_hits_;                                  // L2命中数
    std::atomic<size_t> misses_;                                   // 未命中数

    // 配置选项
    bool write_through_;                                           // 写穿透策略
    bool write_back_;                                              // 写回策略
    bool inclusive_;                                               // 包含性缓存

    // 后台线程相关
    std::thread background_thread_;
    std::atomic<bool> stop_background_;
    std::chrono::seconds sync_interval_;

    // 后台同步任务
    void backgroundSync() {
        while (!stop_background_) {
            std::this_thread::sleep_for(sync_interval_);
            if (!stop_background_) {
                // 定期将L2缓存同步到磁盘
                if (l2_cache_) {
                    l2_cache_->sync();
                }
            }
        }
    }

public:
    // 构造函数
    HierarchicalCache(
        size_t l1_capacity,                                        // L1缓存容量
        size_t l1_max_memory_mb,                                   // L1最大内存限制（MB）
        size_t l2_capacity,                                        // L2缓存容量
        const std::string& l2_cache_dir,                          // L2缓存目录
        size_t l2_max_disk_mb                                      // L2最大磁盘限制（MB）
    ) : total_requests_(0)
      , l1_hits_(0)
      , l2_hits_(0)
      , misses_(0)
      , write_through_(true)                                       // 默认使用写穿透
      , write_back_(false)
      , inclusive_(true)                                           // 默认使用包含性缓存
      , stop_background_(false)
      , sync_interval_(30) {                                       // 默认30秒同步一次

        // 创建L1缓存
        l1_cache_ = std::make_unique<MemoryCache<KeyType, ValueType>>(
            l1_capacity, l1_max_memory_mb
        );

        // 创建L2缓存
        l2_cache_ = std::make_unique<DiskCache<KeyType, ValueType>>(
            l2_capacity, l2_cache_dir, l2_max_disk_mb
        );

        // 设置L1缓存淘汰回调，将淘汰的数据写入L2
        l1_cache_->setEvictionCallback(
            [this](const KeyType& key, const ValueType& value) {
                if (l2_cache_ && inclusive_) {
                    l2_cache_->put(key, value);
                }
            }
        );

        // 启动后台同步线程
        background_thread_ = std::thread(&HierarchicalCache::backgroundSync, this);
    }

    // 析构函数
    ~HierarchicalCache() {
        // 停止后台线程
        stop_background_ = true;
        if (background_thread_.joinable()) {
            background_thread_.join();
        }
    }

    // 向缓存写入数据
    void put(const KeyType& key, const ValueType& value) {
        // 写入L1缓存
        l1_cache_->put(key, value);

        // 根据写策略决定是否同时写入L2
        if (write_through_) {
            // 写穿透：同时写入L2缓存
            l2_cache_->put(key, value);
        }
    }

    // 从缓存读取数据
    bool get(const KeyType& key, ValueType& value) {
        total_requests_++;

        // 首先查询L1缓存
        if (l1_cache_->get(key, value)) {
            l1_hits_++;
            return true;
        }

        // L1未命中，查询L2缓存
        if (l2_cache_->get(key, value)) {
            l2_hits_++;
            // 将数据提升到L1缓存（缓存提升）
            l1_cache_->put(key, value);
            return true;
        }

        // 完全未命中
        misses_++;
        return false;
    }

    // 批量获取数据（优化批量访问）
    std::vector<std::pair<KeyType, ValueType>> getBatch(
        const std::vector<KeyType>& keys
    ) {
        std::vector<std::pair<KeyType, ValueType>> results;
        results.reserve(keys.size());

        for (const auto& key : keys) {
            ValueType value;
            if (get(key, value)) {
                results.emplace_back(key, value);
            }
        }

        return results;
    }

    // 预加载数据到缓存（预热）
    void preload(const std::vector<std::pair<KeyType, ValueType>>& data) {
        for (const auto& [key, value] : data) {
            put(key, value);
        }
    }

    // 删除数据
    void remove(const KeyType& key) {
        l1_cache_->remove(key);
        l2_cache_->remove(key);
    }

    // 清空所有缓存
    void clear() {
        l1_cache_->clear();
        l2_cache_->clear();
        total_requests_ = 0;
        l1_hits_ = 0;
        l2_hits_ = 0;
        misses_ = 0;
    }

    // 检查键是否存在
    bool contains(const KeyType& key) const {
        return l1_cache_->contains(key) || l2_cache_->contains(key);
    }

    // 设置写策略
    void setWritePolicy(bool write_through, bool write_back = false) {
        write_through_ = write_through;
        write_back_ = write_back;
    }

    // 设置包含性策略
    void setInclusivePolicy(bool inclusive) {
        inclusive_ = inclusive;
    }

    // 设置同步间隔
    void setSyncInterval(std::chrono::seconds interval) {
        sync_interval_ = interval;
    }

    // 获取L1缓存引用
    MemoryCache<KeyType, ValueType>& getL1Cache() {
        return *l1_cache_;
    }

    // 获取L2缓存引用
    DiskCache<KeyType, ValueType>& getL2Cache() {
        return *l2_cache_;
    }

    // 获取总体统计信息
    double getOverallHitRate() const {
        size_t total = total_requests_.load();
        if (total == 0) return 0.0;
        return static_cast<double>(l1_hits_.load() + l2_hits_.load()) / total;
    }

    double getL1HitRate() const {
        size_t total = total_requests_.load();
        if (total == 0) return 0.0;
        return static_cast<double>(l1_hits_.load()) / total;
    }

    double getL2HitRate() const {
        size_t total = total_requests_.load();
        if (total == 0) return 0.0;
        return static_cast<double>(l2_hits_.load()) / total;
    }

    double getMissRate() const {
        size_t total = total_requests_.load();
        if (total == 0) return 0.0;
        return static_cast<double>(misses_.load()) / total;
    }

    // 打印综合统计信息
    void printStatistics() const {
        std::cout << "\n========== 分层缓存统计信息 ==========" << std::endl;
        std::cout << "总请求数: " << total_requests_.load() << std::endl;
        std::cout << "L1命中数: " << l1_hits_.load()
                  << " (" << (getL1HitRate() * 100) << "%)" << std::endl;
        std::cout << "L2命中数: " << l2_hits_.load()
                  << " (" << (getL2HitRate() * 100) << "%)" << std::endl;
        std::cout << "未命中数: " << misses_.load()
                  << " (" << (getMissRate() * 100) << "%)" << std::endl;
        std::cout << "总体命中率: " << (getOverallHitRate() * 100) << "%" << std::endl;
        std::cout << "写策略: " << (write_through_ ? "写穿透" : "写回") << std::endl;
        std::cout << "缓存策略: " << (inclusive_ ? "包含性" : "排他性") << std::endl;
        std::cout << "========================================" << std::endl;

        // 打印各层详细信息
        l1_cache_->printStatistics();
        l2_cache_->printStatistics();
    }

    // 手动触发同步
    void forceSync() {
        if (l2_cache_) {
            l2_cache_->sync();
        }
    }
};

#endif // HIERARCHICAL_CACHE_H